﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace UserInterface
{
    [Serializable()]
    public class Map
    {
        //fields
        private Crossing [] myCrossings; // array of crossing....

       public enum status { stopped, paused, playing }; // map statusis it needed? well may be we should leave it for now


        //properties 

       public Crossing getCrossing(int index)
       {
           try
           {
               return myCrossings[index];
           }
           catch (NullReferenceException)
           {
               return null;
           }
       }

        //constructors default one, initializes crossing map list
        public Map()
        {
            myCrossings = new Crossing[7];
            for (int i = 0; i < myCrossings.Length; i++)
                myCrossings[i] = null;
            foundThem = false;
        }

        //methods
        public bool AddCrossing(Crossing c) // adding crossing to the map.
        {                                   // for filling the map with objects of traffic signal
            bool isExist = false;
            if (c == null)
                return false;
            if (myCrossings[c.getIndex()] != null)
            {
                isExist = true;
            }
            // if not exists then adding

            if (!isExist && !myCrossings.Contains(c))
            {
                myCrossings[c.getIndex()]= c;
                foundThem = false;
                return true;
            }
            else return false;
        }

        public bool DeleteCrossing(int index) // delete crossing
        {
            try
            {
                myCrossings[index].pbox.Paint -= new System.Windows.Forms.PaintEventHandler(myCrossings[index].getallCars2Draw);
                myCrossings[index] = null;
                foundThem = false;
                return true;
            }
            catch (NullReferenceException) { return false; }
            catch (System.ArgumentOutOfRangeException)
            {
                return false;
            }
        }

       
        public int getNumberOfCrossings()
        {
            int i=0;
            foreach (Crossing c in myCrossings)
                        if (c != null) i++;
            return i;
        }

        public Crossing[] GetAllCrossings()// get list of crossing
        {

            return myCrossings;
        }

        public void GenerateCars(int numberOfCars) // generating car in the crossing
        {
            foreach (Crossing c in myCrossings)
            {
                try
                {
                    for (int i = 0; i < numberOfCars; i++)
                    {
                        if (c.getNumberOfCars() < 5)
                            c.GenerateCars();
                        
                    }
                }
                catch (NullReferenceException)
                {
                    //break;
                }
            }
        }

        public void GeneratePedo()// generating pedestrian in the crossing type 2
        {

            foreach (Crossing ct2 in myCrossings)
            {
                if (ct2 !=null && ct2.crosType == Parent.Type2)
                {
                    CrossingType2 cr = (CrossingType2)ct2;
                    cr.addPedestrian();
                }
            }
                    
        }

        public void DrawAll()   /// graphics gr object is standard one for printing images on screen through windows forms
        {
            foreach (Crossing c in myCrossings)
            {
                try
                {
                    c.MoveCars();
                }
                catch (NullReferenceException)
                {
                    break;
                }
            }

        }

        public void startSimulation()
        {
            if (!foundThem)
                findNeighbours();

            foreach (Crossing c in myCrossings)
            {
                if (c != null)
                    c.RunMyPattern();
            }
        }
        public void stopSimulation()
        {
            foreach (Crossing c in myCrossings)
            {
                if (c != null)
                {
                    c.StopRunning();
                    c.ResetObjects();
                }
            }
            foundThem = false;
        }

        public void pauseSimulation()
        {
            foreach (Crossing c in myCrossings)
            {
                if (c != null)
                    c.StopRunning();
            }
            
        }
        /// <summary>
        /// True is the findNeighbours pattern has been completed
        /// </summary>
       public bool foundThem = false; 
        private void findNeighbours() 
        {
            // The maximum size of Crossings that the UI can hold
            int maxSize = 7;
            
            // iRow1 = the starting index of the Map as of Crossings
            // iRow2 = the starting index of the crossing underneath the crossing with index iRow1
            // The current grid is sized 3x2
            for (int iRow1 = 1, iRow2 = 4; iRow1 < 4 && iRow2 < maxSize; iRow1++, iRow2++)
            {
                if (myCrossings[iRow1] != null)
                {
                    if (myCrossings[iRow1 + 1] != null)
                        myCrossings[iRow1].AddNeighbour(ref myCrossings[iRow1 + 1]);

                    if (myCrossings[iRow2] != null)
                    {
                        myCrossings[iRow1].AddNeighbour(ref myCrossings[iRow2]);

                        if (iRow2+1 < maxSize && myCrossings[iRow2 + 1] != null )
                            myCrossings[iRow2].AddNeighbour(ref myCrossings[iRow2 + 1]);
                    }
                }
            }
        }
    }
}
